home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 March
/
EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso
/
earcd
/
util4
/
noiz.lha
/
noiz.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-16
|
11KB
|
384 lines
/* noiz.c
*
* Adapted for Amiga computers by C.R. 'Magius' Hahn from noiz-0.5 by
* Henry Strickland <strick@yak.net>. MD5 implementation by Colin Plumb
*
* This is essentially an integrated form of noiz-0.5 for Amiga personal
* computers running OS 2.0 or greater
*
*/
/* Usage: NOIZ [FILE <noizfile>] [TO <file>] [STIR] [ASCII] [INIT]
* If 'TO' keyword is not given, standard output is used, and output
* is ASCII, regardless of the absence of the 'ASCII' switch
*
* FILE keyword specifies noiz state file to use. If not given,
* default is "s:noiz". If the file does not exist, it is
* created and initialized as per INIT switch described below.
* The environment variable, NOIZFILE, is also recognized, and
* overrides the default, but is overridden by the FILE keyword.
* TO keyword specifies output file
* STIR invokes the noizstir function
* ASCII switch causes output to be produced in human-readable form.
* INIT switch causes noise state file to be created and initialized
* before any other action is performed. If the state file already
* exists, a warning is printed, and the file is left unchanged.
* NOTE: As the state file will be automatically created if it does
* not exist, this switch is not really necessary.
*
* Examples:
* NOIZ
* prints 16 bytes of noise, in ASCII.
* equivalent to: noizspin | noizout | od
* NOIZ STIR
* 'stirs' the noise state file.
* equivalent to: noizspin | noizstir
* NOIZ TO outfile STIR
* 'stirs' the noise state file and writes 16 bytes of noise to
* outfile.
* equivalent to: noizspin | noizstir
* noizspin | noizout >outfile
* NOIZ TO outfile ASCII
* prints 16 bytes of noise, in ASCII, to outfile.
* equivalent to: noizspin | noizout | od >outfile
* NOIZ FILE=sys:t/noizyfile INIT
* Creates and initializes sys:t/noizyfile, provided it is not
* already present.
* equivalent to: noizinit
* (but acts on sys:t/noizyfile instead of /etc/noiz)
*
*/
#include <exec/types.h>
#include <exec/alerts.h>
#include <dos/dos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <time.h>
#include "md5.h"
/* ARG numbers - we use these to index into Args[] (see below) */
#define ARG_FILE 0
#define ARG_TO 1
#define ARG_STIR 2
#define ARG_ASCII 3
#define ARG_INIT 4
/* standard AmigaDOS version string */
/* Note that the correct form for the date is (dd.mm.yy) */
UBYTE *VerS = "$VER: NOIZ 0.5 (11.01.96) by Henry Strickland <strick@yak.net> Amiga version by C.R. 'Magius' Hahn";
/* Command-line template, used by ReadArgs system call */
UBYTE *Template = "FILE/K,TO/K,STIR/S,ASCII/S,INIT/S";
struct RDargs *rda=NULL; /* 'placeholder' used by ReadArgs */
UBYTE *Args[5] = { /* ReadArgs fills this in for us */
NULL, /* FILE/K keyword arg */
NULL, /* TO/K keywork arg */
NULL, /* STIR/S switch arg */
NULL, /* ASCII/S switch arg */
NULL /* INIT/S switch arg */
};
/* The following two BOOL's are used instead of their */
/* equivalents in Args[] to implement some rather */
/* obscure behavior (see docs) */
BOOL Produce_Output = FALSE;
BOOL ASCII_Output = FALSE;
/* What's the name of the noise state file? */
UBYTE *StateFile = "S:noiz";
UBYTE sfBuf[80];
/* Exec Library base pointer - this is set up by the starup code, */
/* but we need to be able to examine it to determine what version */
/* of the OS we are running under */
extern struct Library *SysBase;
void safecleanup(void);
BOOL statefile_exists(void);
BOOL init_statefile(void);
int main(void)
{
/* First, make sure we are running under release 2.0 (v36) or */
/* better, because ReadArgs is not present on earlier systems */
/* (also, we want to use buffered IO FGets, FPutc, and so on */
/* which are not present pre-v36 */
if(SysBase->lib_Version < 36)
{
/* OS is too primitive for us, tell user to get a life. */
/* Write is used here to avoid having to bring in */
/* stdio from c.lib - makes the prog smaller */
Write(Output(),"AmigaOS release 2.0 or higher required.\n",40);
return(RETURN_FAIL);
}
/* great, now we register our 'cleanup' function with atexit, so */
/* we don't have to worry about freeing resources if we have to */
/* bail out later */
if(atexit(safecleanup))
{
/* oh-oh, this should never happen - if it does, the */
/* machine is probably so screwed up it'll never be */
/* able to execute any code we might put here.. */
/* The system call, Alert(), probably has the best */
/* shot here, so we'll try that.. Since we don't */
/* know what actually caused us to get screwed up */
/* we'll pass AN_Unknown as an alert code */
Alert(AN_Unknown);
return(RETURN_FAIL);
}
rda = ReadArgs(Template, Args, NULL);
if(!rda)
{
/* Again, this should not happen, */
Alert(AN_Unknown);
return(RETURN_FAIL);
}
/* Now, set up our additional globals */
/* produce output only if neither of INIT or STIR are given, OR */
/* if output is implicitly enabled via TO or ASCII */
Produce_Output = (!(Args[ARG_STIR] || Args[ARG_INIT])) || (Args[ARG_TO] || Args[ARG_ASCII]);
ASCII_Output = Args[ARG_ASCII] || (!Args[ARG_TO]);
/* Now decide where the noise state file can be found. This */
/* would be /etc/noiz under UNIX, but we default to S:noiz */
/* We also allow the user to specify a different file via the */
/* command line, or an environment variable */
if(Args[ARG_FILE]) StateFile = Args[ARG_FILE];
else
{
BPTR sfile;
sfile = Open("ENV:NOIZFILE",MODE_OLDFILE);
if(sfile)
{
FGets(sfile,sfBuf,80);
StateFile = sfBuf;
Close(sfile);
}
}
if(statefile_exists())
{
if(Args[ARG_INIT])
{
/* Rather that print our own error message here, I */
/* have DOS perform the task, since DOS (2.1 or better) */
/* knows how to print an error message in the user's */
/* preferred language. *Objekt existiert bereits* */
PrintFault(ERROR_OBJECT_EXISTS,StateFile);
}
}
else
{
/* If the statefile doesn't exist, create and initialize it. */
if(!init_statefile())
{
/* DAMN.. can't create statefile - maybe the user */
/* gave a faulty filename. Let DOS handle this */
PrintFault(IoErr(),StateFile);
return(RETURN_FAIL);
}
}
if(Args[ARG_STIR])
{
BYTE noiz[256];
BYTE pad[256];
UBYTE in_hash[16];
UBYTE out_hash[16];
struct MD5Context context;
int e,i,seconds,row;
long pid;
long ppid;
BPTR fh;
/* Seed the c.lib's pseudorandom number generator */
/* which we use because we don't really have */
/* anything better (this replaces noizspin) */
srand(time(NULL)^(ULONG)FindTask(NULL));
/* This stuff is basically the same as the original noizstir */
/* code except that we use AmigaDOS calls instead of stdio */
fh = Open(StateFile,MODE_OLDFILE);
if(!fh)
{
PrintFault(IoErr(),StateFile);
return(RETURN_FAIL);
}
Read(fh,noiz,256);
MD5Init( &context );
MD5Update(&context, noiz, 256);
sprintf(pad,"%d",rand());
MD5Update(&context, pad, 256);
time( &seconds );
pid= rand();
ppid= FindTask(NULL);
MD5Update( &context, (UBYTE *) &seconds, sizeof seconds );
MD5Update( &context, (UBYTE *) &pid, sizeof pid );
MD5Update( &context, (UBYTE *) &ppid, sizeof ppid );
MD5Final( in_hash, &context );
for (row=0; row<16; row++ ) {
MD5Init( &context );
MD5Update( &context, noiz+16*row, 16 );
MD5Update( &context, in_hash, 16 );
MD5Update( &context, in_hash, row+1 );
MD5Final( out_hash, &context );
for ( i=0; i<16; i++ ) {
noiz[16*row+i] ^= out_hash[i];
}
}
Seek(fh,0,OFFSET_BEGINNING);
e = Write(fh, noiz, 256);
if(e == -1)
{
PrintFault(IoErr(),StateFile);
}
Close(fh);
}
if(Produce_Output)
{
BYTE noiz[256];
BYTE pad[256];
UBYTE out_hash[16];
struct MD5Context context;
int seconds, pid, ppid;
BPTR fh;
/* Seed the c.lib's pseudorandom number generator */
/* which we use because we don't really have */
/* anything better */
srand(time(NULL)^(LONG)FindTask(NULL));
/* This stuff is basically the same as the original noizout */
/* code except that we use AmigaDOS calls instead of stdio */
fh = Open(StateFile,MODE_OLDFILE);
if(!fh)
{
PrintFault(IoErr(),StateFile);
return(RETURN_FAIL);
}
Read(fh, noiz, 256);
Close(fh);
sprintf(pad,"%d\n",rand());
MD5Init( &context );
MD5Update(&context, noiz, 256);
MD5Update(&context, pad, 256);
time( &seconds );
pid= rand();
ppid= FindTask(NULL);
MD5Update( &context, (UBYTE *) &seconds, sizeof seconds );
MD5Update( &context, (UBYTE *) &pid, sizeof pid );
MD5Update( &context, (UBYTE *) &ppid, sizeof ppid );
MD5Final( out_hash, &context );
if(Args[ARG_TO])
{
fh = Open(Args[ARG_TO],MODE_NEWFILE);
if(!fh)
{
PrintFault(IoErr(),Args[ARG_TO]);
return(RETURN_FAIL);
}
if(Args[ARG_ASCII])
{
char out[20];
int j;
FPuts(fh,"0x");
for(j=0;j<16;j++)
{
sprintf(out,"%02X",out_hash[j]);
FPuts(fh,out);
}
FPuts(fh,"\n");
}
else
{
Write(fh,out_hash,16);
}
Close(fh);
}
else
{
char out[20];
int j;
PutStr("0x");
for(j=0;j<16;j++)
{
sprintf(out,"%02X",out_hash[j]);
PutStr(out);
}
PutStr("\n");
}
}
return(RETURN_OK);
}
BOOL statefile_exists(void)
{
BPTR lock;
BOOL rv;
lock = Lock(StateFile,SHARED_LOCK);
if(lock)
{
rv = TRUE;
UnLock(lock);
}
else rv = FALSE;
return(rv);
}
BOOL init_statefile(void)
{
BPTR file;
int i, e;
file = Open(StateFile,MODE_NEWFILE);
if(!file)
{
return(FALSE);
}
for(i=0; i<256; i++)
{
e = FPutC(file,i);
if(e < 0)
{
Close(file);
return(FALSE);
}
}
Close(file);
return(TRUE);
}
void safecleanup(void)
{
if(rda) FreeArgs(rda);
}